[comment encoding = UTF-8 /] [** * Copyright 2014 Alessandro Gerlinger Romero * * This file is part of Hybrid fUML. * * Hybrid fUML is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Hybrid fUML is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Hybrid fUML. If not, see . * * THIS transformation receives a model and generates all the elements to support the static semantics for composite structures. * * DEFINED BY BASE SEMANTICS */] [module embeddingM1_CLIF('http://www.eclipse.org/uml2/4.0.0/UML')] [** * The documentation of the template generateElement. * @param aClass */] [template public generateModel(aModel : Model)] [comment @main/] [file ('syntax_userModel_embedded.clf', false, 'UTF-8')] [Classifier.allInstances().generateClassifier()/] [/file] [/template] [template public generateClassifier(aClassifier : Classifier)] (buml:Classifier [generateName(aClassifier)/]) [if (aClassifier.general->size() = 0)] (not (exists (e) (buml:general [generateName(aClassifier)/] e))) [/if] [for (gClassifier:Classifier | aClassifier.general)] (buml:general [generateName(aClassifier)/] [generateName(gClassifier)/]) [/for] [let aClass : Class = aClassifier] [generateClass(aClass)/] [/let] [let aBehavior : Behavior = aClassifier] [generateBehavior(aBehavior)/] [for (p:Parameter | aBehavior.ownedParameter)] (buml:ownedParameter [generateName(aBehavior)/] [generateName(p)/]) [generateParameter(p)/][/for] [/let] [let aAssociation : Association = aClassifier] [generateAssociationPlusPlus(aAssociation)/] [/let] [let aDataType : DataType = aClassifier] [generateDataTypePlusPlus(aDataType)/] [/let] [/template] [template public generateClass(aClass : Class)] (buml:Class [generateName(aClass)/]) [if (aClass.ownedAttribute->size() = 0)] (not (exists (e) (buml:ownedAttribute [generateName(aClass)/] e))) [/if] [for (p:Property | aClass.ownedAttribute)] (buml:ownedAttribute [generateName(aClass)/] [generateName(p)/]) [generateProperty(p)/] [/for] [if (aClass.classifierBehavior->size() = 0)] (not (exists (e) (buml:classifierBehavior [generateName(aClass)/] e))) [else] (buml:classifierBehavior [generateName(aClass)/] [generateName(aClass.classifierBehavior)/]) [/if] [generateClassPlusPlus(aClass)/] [/template] [template public generateOperation(o : Operation)] (buml:Operation [generateName(o)/]) [for (p:Parameter | o.ownedParameter)] (buml:ownedParameter [generateName(o)/] [generateName(p)/]) [generateParameter(p)/][/for] [generateBehavioralPlusPlus(o)/] [/template] [template public generateProperty(p : Property)] (buml:Property [generateName(p)/]) [if (p.aggregation = AggregationKind::composite)](buml:aggregation [generateName(p)/] buml:[p.aggregation/])[/if] [generateType(p,p)/] [generateMultiplicity(p, p)/] [generatePropertyPlusPlus(p)/] [/template] [template public generateParameter(p : Parameter) ] (buml:Parameter [generateName(p)/]) [if (p.direction = ParameterDirectionKind::_in)](buml:direction [generateName(p)/] buml:in)[/if] [if (p.direction = ParameterDirectionKind::_out)](buml:direction [generateName(p)/] buml:out)[/if] [if (p.direction = ParameterDirectionKind::_return)](buml:direction [generateName(p)/] buml:return)[/if] [generateType(p,p)/] [generateMultiplicity(p, p)/] [/template] [template public generateType(t : TypedElement, n:NamedElement) ] [let t:Type = t.type](buml:type [generateName(n)/] [if (t.namespace.name = 'PrimitiveTypes')]buml:[t.name /][else][generateName(t)/][/if])[generateDataTypePlusPlus(t)/][else](not (exists (e) (buml:type [generateName(n)/] e)))[/let] [/template] [template public generateMultiplicity(m : MultiplicityElement, n:NamedElement)] [let v:LiteralInteger = m.lowerValue](buml:lower [generateName(n)/] [generateNumber(v.value)/])[else](not (exists (e) (buml:lower [generateName(n)/] e)))[/let] [let v:LiteralUnlimitedNatural = m.upperValue](buml:upper [generateName(n)/] [generateNumber(v.value)/])[else](not (exists (e) (buml:upper [generateName(n)/] e)))[/let] [/template] [template public generateNumber(n : Integer)] [if (n = -1)]buml:*[elseif (n = 0)]form:0[elseif (n = 1)]form:1[else][n/][/if] [/template] [template public generateName(n:NamedElement)] [let nOw:NamedElement = n.owner][generateName(nOw)/]::[/let][n.name/] [/template] [template public generateBehavior(aBehavior : Behavior)] (buml:Behavior [generateName(aBehavior)/]) [let f:FunctionBehavior = aBehavior] (buml:FunctionBehavior [generateName(aBehavior)/]) [/let] [/template] [** * DEFINED BY RULES - PROPOSED */] [template public generateClassPlusPlus(aClass : Class)] [if (not aClass.isActive)](not [/if](cbuml:isActive [generateName(aClass)/] form:true)[if (not aClass.isActive)])[/if] [if (not aClass.isAbstract)](not [/if](cbuml:isAbstract [generateName(aClass)/] form:true)[if (not aClass.isAbstract)])[/if] [if (aClass.ownedOperation->size() = 0)] (not (exists (e) (cbuml:ownedOperation [generateName(aClass)/] e))) [/if] [for (o:Operation | aClass.ownedOperation)] (cbuml:ownedOperation [generateName(aClass)/] [generateName(o)/]) [generateOperation(o)/] [/for] [if (aClass.ownedBehavior->size() = 0)] (not (exists (e) (cbuml:ownedBehavior [generateName(aClass)/] e))) [/if] [for (aBehavior : Behavior | aClass.ownedBehavior)] (cbuml:ownedBehavior [generateName(aClass)/] [generateName(aBehavior)/]) [generateBehavior(aBehavior)/] [/for] [if (aClass.ownedReception->size() = 0)] (not (exists (e) (cbuml:ownedReception [generateName(aClass)/] e))) [/if] [for (aReception : Reception | aClass.ownedReception)] (cbuml:Reception [generateName(aReception)/]) (cbuml:ownedReception [generateName(aClass)/] [generateName(aReception)/]) [generateBehavioralPlusPlus(aReception)/] [/for] [for (aConnector : Connector | aClass.ownedConnector)] (cbuml:ownedConnector [generateName(aClass)/] [generateName(aConnector)/]) [generateConnectorPlusPlus(aConnector)/] [/for] [/template] [template public generateBehavioralPlusPlus(aBehavioralF : BehavioralFeature)] (cbuml:BehavioralFeature [generateName(aBehavioralF)/]) [if (not aBehavioralF.isAbstract)](not [/if](cbuml:isAbstract [generateName(aBehavioralF)/] form:true)[if (not aBehavioralF.isAbstract)])[/if] (cbuml:visibility [generateName(aBehavioralF)/] cbuml:[aBehavioralF.visibility/]) [/template] [template public generateDataTypePlusPlus(aType : Type)] [let aDataType:DataType = aType] (cbuml:DataType [if (aDataType.namespace.name = 'PrimitiveTypes')]buml:[aDataType.name /][else][generateName(aDataType)/][/if]) [for (p:Property | aDataType.ownedAttribute)] (buml:ownedAttribute [generateName(aDataType)/] [generateName(p)/]) [generateProperty(p)/] [/for] [for (o:Operation | aDataType.ownedOperation)] (cbuml:ownedOperation [generateName(aDataType)/] [generateName(o)/]) [generateOperation(o)/] [/for] [/let] [/template] [template public generateAssociationPlusPlus(aAssociation : Association)] (cbuml:Association [generateName(aAssociation)/]) [if (aAssociation.memberEnd->size() = 0)] (not (exists (e) (cbuml:memberEnd [generateName(aAssociation)/] e))) [/if] [for (aProperty : Property | aAssociation.memberEnd)] (cbuml:memberEnd [generateName(aAssociation)/] [generateName(aProperty)/]) [if (aAssociation.navigableOwnedEnd->includes(aProperty))] (cbuml:navigableOwnedEnd [generateName(aAssociation)/] [generateName(aProperty)/]) [else] (not (cbuml:navigableOwnedEnd [generateName(aAssociation)/] [generateName(aProperty)/])) [/if] [generateProperty(aProperty)/] [/for] [if (aAssociation.ownedEnd->size() = 0)] (not (exists (e) (cbuml:ownedEnd [generateName(aAssociation)/] e))) [/if] [for (aProperty : Property | aAssociation.memberEnd)] (cbuml:ownedEnd [generateName(aAssociation)/] [generateName(aProperty)/]) [/for] [if (aAssociation.navigableOwnedEnd->size() = 0)] (not (exists (e) (cbuml:navigableOwnedEnd [generateName(aAssociation)/] e))) [/if] [/template] [template public generatePropertyPlusPlus(p : Property) ] (cbuml:visibility [generateName(p)/] cbuml:[p.visibility/]) [let aPort : Port = p ] (cbuml:Port [generateName(aPort)/]) [if (not aPort.isConjugated)](not [/if](cbuml:isConjugated [generateName(aPort)/] form:true)[if (not aPort.isConjugated)])[/if] [if (not aPort.isBehavior)](not [/if](cbuml:isBehavior [generateName(aPort)/] form:true)[if (not aPort.isBehavior)])[/if] [if (ConnectorEnd.allInstances()->select(end->exists(cone|cone.role = aPort))->size() = 0)] (not (exists (e) (cbuml:role e [generateName(aPort)/]))) [/if] [if (not aPort.isConjugated)] [if (getAllTypesOtherEndExcludingParts(aPort, ConnectorKind::assembly)->isEmpty() or aPort.type->getAllAbstractGeneralsIncludingMe()->includesAll(getAllTypesOtherEndExcludingParts(aPort, ConnectorKind::assembly)->getAllAbstractGeneralsIncludingMe()))] (form:port-covers-assemblies [generateName(aPort)/]) [else] (not (form:port-covers-assemblies [generateName(aPort)/])) [/if] [if (getAllTypesOtherEnd(aPort, ConnectorKind::delegation)->isEmpty() or getAllTypesOtherEnd(aPort, ConnectorKind::delegation)->getAllAbstractGeneralsIncludingMe()->includesAll(aPort.type->getAllAbstractGeneralsIncludingMe()))] (form:port-covers-delegations [generateName(aPort)/]) [else] (not (form:port-covers-delegations [generateName(aPort)/])) [/if] [/if] [if (aPort.isConjugated)] [if (getAllTypesOtherEnd(aPort, ConnectorKind::assembly)->isEmpty() or getAllTypesOtherEnd(aPort, ConnectorKind::assembly)->getAllAbstractGeneralsIncludingMe()->includesAll(aPort.type->getAllAbstractGeneralsIncludingMe()))] (form:port-covers-assemblies [generateName(aPort)/]) [else] (not (form:port-covers-assemblies [generateName(aPort)/])) [/if] [if (getAllTypesOtherEndExcludingParts(aPort, ConnectorKind::delegation)->isEmpty() or aPort.type->getAllAbstractGeneralsIncludingMe()->includesAll(getAllTypesOtherEndExcludingParts(aPort, ConnectorKind::delegation)->getAllAbstractGeneralsIncludingMe()))] (form:port-covers-delegations [generateName(aPort)/]) [else] (not (form:port-covers-delegations [generateName(aPort)/])) [/if] [/if] [for ( type: Type | getAllTypesOtherEnd(aPort, ConnectorKind::assembly))] [for ( type1: Type | getAllTypesOtherEnd(aPort, ConnectorKind::assembly))] [if ( type->getAllAbstractGeneralsIncludingMe()->symmetricDifference(type1->getAllAbstractGeneralsIncludingMe())->isEmpty())] (not (form:port-ambiguous-assembly [generateName(aPort)/] [generateName(type)/] [generateName(type1)/])) [else] (form:port-ambiguous-assembly [generateName(aPort)/] [generateName(type)/] [generateName(type1)/]) [/if] [/for] [/for] [if (getAllTypesOtherEnd(aPort, ConnectorKind::assembly)->size() = 0)] (not (exists (e1 e2)(form:port-ambiguous-assembly [generateName(aPort)/] e1 e2))) [/if] [for ( type: Type | getAllTypesOtherEnd(aPort, ConnectorKind::delegation))] [for ( type1: Type | getAllTypesOtherEnd(aPort, ConnectorKind::delegation))] [if ( type->getAllAbstractGeneralsIncludingMe()->symmetricDifference(type1->getAllAbstractGeneralsIncludingMe())->isEmpty())] (not (form:port-ambiguous-delegation [generateName(aPort)/] [generateName(type)/] [generateName(type1)/])) [else] (form:port-ambiguous-delegation [generateName(aPort)/] [generateName(type)/] [generateName(type1)/]) [/if] [/for] [/for] [if (getAllTypesOtherEnd(aPort, ConnectorKind::delegation)->size() = 0)] (not (exists (e1 e2) (form:port-ambiguous-delegation [generateName(aPort)/] e1 e2))) [/if] [for ( otherPort: Port | getAllPortsOtherEnd(aPort))] (form:port-related [generateName(aPort)/] [generateName(otherPort)/]) [/for] [if (getAllPortsOtherEnd(aPort)->size() = 0)] (not (exists(e) (form:port-related [generateName(aPort)/] e))) [/if] [for ( conn: Connector | getAllConnectors(aPort, ConnectorKind::assembly))] (form:port-conn-assembly [generateName(aPort)/] [generateName(conn)/]) [/for] [if (getAllConnectors(aPort, ConnectorKind::assembly)->size() = 0)] (not (exists(e) (form:port-conn-assembly [generateName(aPort)/] e))) [/if] [for ( conn: Connector | getAllConnectors(aPort, ConnectorKind::delegation))] (form:port-conn-delegation [generateName(aPort)/] [generateName(conn)/]) [/for] [if (getAllConnectors(aPort, ConnectorKind::delegation)->size() = 0)] (not (exists(e) (form:port-conn-delegation [generateName(aPort)/] e))) [/if] [/let] [/template] [** * IMPORTANT - BECAUSE conjugated ports connected to parts does not mandate interfaces on the parts */] [query public getAllTypesOtherEndExcludingParts(port : Port, pkind: ConnectorKind) : Set (Type) = Connector.allInstances()->select(kind=pkind)->select(con|con.end->exists(cone|cone.role = port)).end->select(cone|not (cone.role = port))->reject(cone|cone.role.type = null)->reject(cone|cone.partWithPort=null).role.type->asSet() /] [query public getAllTypesOtherEnd(port : Port, pkind: ConnectorKind) : Set (Type) = Connector.allInstances()->select(kind=pkind)->select(con|con.end->exists(cone|cone.role = port)).end->select(cone|not (cone.role = port))->reject(cone|cone.role.type = null).role.type->asSet() /] [query public getAllPortsOtherEnd(port : Port) : Set (Port) = Connector.allInstances()->select(con|con.end->exists(cone|cone.role = port)).end->select(cone|not (cone.role = port)).role->filter(Port)-> asSet() /] [query public getAllConnectors(port : Port, pkind: ConnectorKind) : Set (Connector) = Connector.allInstances()->select(kind=pkind)->select(con|con.end->exists(cone|cone.role = port)) /] [query public getAllAbstractGeneralsIncludingMe(classifier : Set(Type)) : Set (Type) = classifier->closure(a|a.oclAsType(Classifier).general)->selectClassesAbstractWithOperationsOrReceptions() -> union(classifier.oclAsType(Classifier)->asSet()->selectClassesAbstractWithOperationsOrReceptions()) /] [query public selectClassesAbstractWithOperationsOrReceptions(classifier : Set(Classifier)) : Set (Classifier) = classifier->select(isAbstract)->select(a|a.oclAsType(Class).ownedAttribute -> size() >0 or a.oclAsType(Class).ownedOperation-> size() >0 or a.oclAsType(Class).ownedAttribute-> size() >0) /] [template public generateConnectorPlusPlus(aConnector : Connector)] (cbuml:visibility [generateName(aConnector)/] cbuml:[aConnector.visibility/]) (cbuml:Connector [generateName(aConnector)/]) (cbuml:kind [generateName(aConnector)/] cbuml:[aConnector.kind/]) [let t:Association = aConnector.type] (cbuml:type [generateName(aConnector)/] [generateName(t)/]) [else] (not (exists (e) (cbuml:type [generateName(aConnector)/] e))) [/let] [if (aConnector.end->size() = 0)] (not (exists (e) (cbuml:end [generateName(aConnector)/] e))) [/if] [for (aConnectorEnd : ConnectorEnd | aConnector.end)] (cbuml:ConnectorEnd [generateName(aConnector)/][i/]) (cbuml:end [generateName(aConnector)/] [generateName(aConnector)/][i/]) (cbuml:role [generateName(aConnector)/][i/] [generateName(aConnectorEnd.role)/]) [if (aConnectorEnd.partWithPort->size() = 0)] (not (exists (e) (cbuml:partWithPort [generateName(aConnector)/][i/] e))) [else] (cbuml:partWithPort [generateName(aConnector)/][i/] [generateName(aConnectorEnd.partWithPort)/]) [/if] [let v:LiteralInteger = aConnectorEnd.lowerValue] [if (v.value = 1)] (cbuml:lower [generateName(aConnector)/][i/] [generateNumber(v.value)/]) [else] (not (cbuml:lower [generateName(aConnector)/][i/] form:1)) [/if] [else] (not (exists (e) (cbuml:lower [generateName(aConnector)/][i/] e))) [/let] [let v:LiteralUnlimitedNatural = aConnectorEnd.upperValue] [if (v.value = 1)] (cbuml:upper [generateName(aConnector)/][i/] [generateNumber(v.value)/]) [else] (not (cbuml:upper [generateName(aConnector)/][i/] form:1)) [/if] [else] (not (exists (e) (cbuml:upper [generateName(aConnector)/][i/] e))) [/let] [if (aConnector.type <> null and aConnector.type.ownedEnd -> exists (end | end.type.conformsTo(aConnectorEnd.role.type) and aConnectorEnd.lower >= end.lower and (aConnectorEnd.upper <= end.upper or end.upper = -1)))] (form:conform-type-and-multiplicity [generateName(aConnector)/][i/] form:true) [else] (not (form:conform-type-and-multiplicity [generateName(aConnector)/][i/] form:true)) [/if] [if (aConnector.type <> null and aConnector.type.ownedEnd -> exists (end | end.type.conformsTo(aConnectorEnd.role.type) and aConnector.type.navigableOwnedEnd->includes(end)))] (form:is-navegable [generateName(aConnector)/][i/] form:true) [else] (not (form:is-navegable [generateName(aConnector)/][i/] form:true)) [/if] [if (aConnector.type <> null and aConnector.type.ownedEnd -> exists (end | end.type = aConnectorEnd.role.owner and aConnectorEnd.role.oclIsTypeOf(Port)))] (form:directed-to-port-owner [generateName(aConnector)/][i/] form:true) [else] (not (form:directed-to-port-owner [generateName(aConnector)/][i/] form:true)) [/if] [/for] [if (aConnector.end->size() = 2)] (form:end-size [generateName(aConnector)/] form:2) (form:connector-end-related[for (aConnectorEnd : ConnectorEnd | aConnector.end)] [generateName(aConnector)/][i/][/for]) [else] (not (form:end-size [generateName(aConnector)/] form:2)) [/if] [/template]